#!/usr/bin/env python
#
# Copyright 2010 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""BuzzSyncHandler simplifies synchonizing Google Buzz data to the datastore.

BuzzSyncHandler is a webapp.RequestHandler that connects to Google Buzz via
the Google Buzz API, searches for a series of buzz, and then stores the words
from those buzz into gfemmebot's datastore.
"""


__author__ = 'Vic Fryzel <vicfryzel@google.com>'


import logging
import re
import time
from gfemmebot.buzz import buzz
from gfemmebot.word_list import WordList
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app


def strip(value):
  """Strip things not useful for Markov chaining from the given string.

  Args:
    value: string The string to strip of HTML, non-alpha characters, etc.
  Returns:
    The given string with HTML, @ mentions, # tags, extra whitespace, and
    non-alpha characters removed.
  """
  value = re.sub(r'<.*?>', '', value)
  value = re.sub(r'[@]\S*', '', value)
  value = re.sub(r'http://\S*', '', value)
  value = re.sub(r'[^a-zA-Z]', ' ', value)
  value = re.sub(r'\s\s*', ' ', value)
  return value


class BuzzSyncHandler(webapp.RequestHandler):
  """The cron job used to sync the local word list with Google Buzz."""

  # The words to use when querying Buzz for posts.
  queries = ['linux']
  client = None
  
  def init_client(self):
    if self.client is None:
      self.client = buzz.Client()
      self.client.use_anonymous_oauth_consumer()

  def get_words(self):
    """Get a list of words from the Buzz API based on the given queries.

    Returns:
      A string of all words found in buzz returned by the Buzz API for
      this handler's queries.
    """
    words = ''
    self.init_client()
    for q in self.queries:
      results = self.client.search(query=q)
      try:
        for result in results:
          try:
            words += strip(result.content)
            words += ' '
          except UnicodeEncodeError:
            pass
      except TypeError:
        pass
      except buzz.RetrieveError:
        # Raised after we hit the last item in the feed
        pass
      # Try to avoid hitting a quota
      time.sleep(3)
    return words
  
  def update(self):
    """Update gfemmebot's datastore with new words."""
    word_list = WordList()
    word_list.words = self.get_words()
    word_list.put()

  def truncate(self):
    """Truncate gfemmebot's datastore contents so we can add fresh words."""
    q = db.GqlQuery("SELECT * FROM WordList")
    for result in q:
        result.delete()

  def get(self):
    """truncate(), update(), and yield "success" if everything went well."""
    self.truncate()
    self.update()
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write('success')


# The application container to run a BuzzSyncHandler and bind it to
# /sync/buzz/.
application = webapp.WSGIApplication(
    [('/sync/buzz/', BuzzSyncHandler)], debug=True) 

def main():
  """Run the BuzzSyncHandler application."""
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
